# -*- coding: utf-8 -*-
"""
@Time ： 2021/5/13 15:16
@Auth ： Mr. royalday 2487625775
@Company ：XXX
@Function ：腾讯云对象存储服务
"""
# appid 已在配置中移除,请在参数 Bucket 中带上 appid。Bucket 由 BucketName-APPID 组成
# 1. 设置用户配置, 包括 secretId，secretKey 以及 Region
from qcloud_cos import CosConfig, CosServiceError
from qcloud_cos import CosS3Client
from sts.sts import Sts
from django.conf import settings
import sys
import logging


def init_cos(secret_id="", secret_key="", region=""):
    """
    初始化，创建对象存储客户端对象
    :param secret_id:
    :param secret_key:
    :param region:
    :return:
    """
    if secret_id is "" or secret_id is None:
        secret_id = settings.TENCENT_COS['secret_id']  # 替换为用户的 secretId
    if secret_key is "" or secret_key is None:
        secret_key = settings.TENCENT_COS['secret_key']  # 替换为用户的 secretKey
    if region is "" or region is None:
        region = settings.TENCENT_COS['region']  # 替换为用户的 Region, 区域名称

    logging.basicConfig(level=logging.INFO, stream=sys.stdout)
    token = None  # 使用临时密钥需要传入 Token，默认为空，可不填
    scheme = 'https'  # 指定使用 http/https 协议来访问 COS，默认为 https，可不填

    proxies = {
        'http': '127.0.0.1:80',  # 替换为用户的 HTTP代理地址
        'https': '127.0.0.1:443'  # 替换为用户的 HTTPS代理地址
    }

    endpoint = 'cos.accelerate.myqcloud.com'  # 替换为用户的 endpoint

    # domain 自定义域名，通常不用设置，如果使用全球加速域名，则设置成对应的域名，例如 examplebucket-1250000000.cos.accelerate.myqcloud.com，
    # 开启全球加速请参考 https://cloud.tencent.com/document/product/436/38864
    domain = 'examplebucket-1250000000.cos.accelerate.myqcloud.com'

    config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
    # 2. 获取客户端对象
    client = CosS3Client(config)
    # 参照下文的描述。或者参照 Demo 程序，详见 https://github.com/tencentyun/cos-python-sdk-v5/blob/master/qcloud_cos/demo.py
    return client


def create_bucket(bucketName="", region=""):
    """
    创建桶
    :param region: 区域
    :param bucketName: 桶名称
    :return:
    """
    client = init_cos(region=region)

    response = client.create_bucket(
        Bucket=bucketName,
        ACL="public-read"  # private 私有的只能自己读写  /  public-read 公有读私有写 / public-read-write 公有读写
    )

    # 桶的跨域访问CORS设置
    cors_config = settings.CORS_CONFIG

    # 设置桶的跨域访问CORS配置
    client.put_bucket_cors(
        Bucket=bucketName,
        CORSConfiguration=cors_config,
    )

    return response


def upload_file(bucketName, region="", localFilePath="", key=""):
    """
    上传文件到cos对象存储
    :param region: 区域
    :param bucketName: 桶名称
    :param localFilePath: 本地文件路径
    :param key: 上传到桶后的文件名称
    :return:
    """
    client = init_cos(region=region)
    response = client.upload_file(
        Bucket=bucketName,
        LocalFilePath=localFilePath,
        Key=key,
        PartSize=1,
        MAXThread=10,
        EnableMD5=False
    )
    res_url = f"https://{bucketName}.cos.{region}.myqcloud.com/{key}"
    return res_url


def upload_buffer_file(bucketName, region, file_object, key):
    """
    上传文件对象到cos桶
    :param region: 区域
    :param bucketName: 桶名
    :param file_object: 文件对象
    :param key: 上传成功后文件名称
    :return:
    """
    client = init_cos()
    response = client.upload_file_from_buffer(
        Bucket=bucketName,
        Body=file_object,
        Key=key,
    )
    # https://test2021-05-13-16-42-11-1305644719.cos.ap-nanjing.myqcloud.com/%E5%BE%A1%E5%A4%A9.png
    res_url = f"https://{bucketName}.cos.{region}.myqcloud.com/{key}"
    return res_url


def delete_file(bucket, key, region=""):
    """
    删除cos桶中的文件
    :param region:
    :param bucket:
    :param key:
    :return:
    """
    print(bucket)
    print(key)
    print(region)
    client = init_cos(region=region)
    client.delete_object(
        Bucket=bucket,
        Key=key
    )
    return True


# def delete_file_list()


def credential(bucket, region):
    """

    :return:
    """

    config = {
        # l临时密钥有效时长,单位是秒(30分钟=1800秒)
        "duration_seconds": 1800,
        # 固定密钥id
        "secret_id": settings.TENCENT_COS['secret_id'],
        # 固定密钥key
        "secret_key": settings.TENCENT_COS['secret_key'],
        # 换成你的bucket
        "bucket": bucket,
        # 换成bucket所在地区
        'region': region,
        # 这里改成允许的路径前缀，可以根据自己网站的用户登录态判断允许上传的具体路径#例子: a.jpg 或者a/*或者*（使用通配符*存在重大安全风险，请谨慎评估使用)
        'allow_prefix': '*',
        # 密钥的权限列表。简单上传和分片需要以下的权限，其他权限列表请看 https://cloud.tencent .com/ document/ product/436/31923
        'allow_actions': [
            # "name/cos:PutObject",
            # ' name/cos:PostObject',
            # "name/cos: DeleteObject' ,
            # "name/cos: UploadPart"" ,
            # "name/cos: UploadPartCopy" ,
            # "name/cos: CompleteMultipartUpload"" ,
            # "name/cos: AbortMultipartUpload"" ,
            "*",
        ],
    }
    sts = Sts(config)
    result_dict = sts.get_credential()
    return result_dict


def check_file(bucket, key, region=""):
    """
    校验文件是否合法
    :param bucket:
    :param key:
    :param region:
    :return: 根据key桶中的文件
    """
    client = init_cos(region=region)
    data = client.head_object(
        Bucket=bucket,
        Key=key
    )
    return data


def delete_bucket(bucket, region):
    """
    删除桶
    :param bucket: 桶名称
    :param region: 区域
    :return: 成功失败
    """
    client = init_cos(region=region)

    # 1、删除桶内的所有完整文件
    if bucket is None:
        return False
    try:
        while True:
            part_objects = client.list_objects(bucket)  # 最多返回1000条记录

            # 查看是否已经获取所有文件，获取不到文件时，不会携带contents
            contents = part_objects.get('Contents')
            print(1)
            if not contents:
                break

            # 执行批量删除文件
            objects = {
                'Quiet': 'true',
                'Object': [{'Key': item['Key']} for item in contents]
            }
            client.delete_objects(bucket, objects)

            # 删除文件后再判断下是否截断，如果为true表示这只是一部分，后面还有文件，继续执行循环
            if part_objects['IsTruncated'] == 'false':
                break

        # 2、删除桶内的所有文件碎片
        while True:
            part_upload_objects = client.list_multipart_uploads(bucket)  # 获取所有的碎片文件
            uploads = part_upload_objects.get('Upload')  # 检查是否还存在碎片文件，如果不存在退出循环
            if not uploads:
                break
            print(2)
            # 删除所有碎片文件
            for item in uploads:
                client.abort_multipart_upload(bucket, item['Key'], item['UploadId'])

            # 删除文件后再判断下是否截断，如果为true表示这只是一部分，后面还有文件，继续执行循环
            if part_objects['IsTruncated'] == 'false':
                break

        # 3、删除桶
        client.delete_bucket(bucket)
    except Exception as e:
        return False
    
    return True


if __name__ == '__main__':
    #  print(create_bucket(bucketName="test"))
    # localFile = r'C:\Users\royalday\Pictures\Camera Roll\御天.png'
    # upload_file(bucketName='test2021-05-13-16-42-11-1305644719', localFilePath=localFile, key='御天.png')
    res = credential(bucket='15879924717-2021-05-18-11-26-15-1305644719', region='ap-nanjing')
    print(res)
